<script>
import { defineComponent, nextTick, onMounted, ref, watch } from 'vue';

import {
  Button,
  Dropdown,
  DropdownButton,
  Menu,
  message,
  Modal,
} from 'ant-design-vue';
import Descriptions from 'ant-design-vue/es/descriptions';
import Input from 'ant-design-vue/es/input';

import { useMapStore } from '#/store/map';

export default defineComponent({
  name: 'AMapLocation',
  components: {
    AInput: Input,
    AInputGroup: Input.Group,
    AButton: Button,
    ADescriptions: Descriptions,
    ADescriptionsItem: Descriptions.Item,
    ADropdown: Dropdown,
    ADropdownButton: DropdownButton,
    AMenu: Menu,
    AModal: Modal,
  },
  props: {
    modelValue: {
      type: Array,
      default: () => [],
    },
    defaultSearch: {
      type: String,
      default: '',
    },
    cityValue: {
      type: String,
      default: '',
    },
    // 是否可拖拽
    draggable: {
      type: Boolean,
      default: true,
    },
    width: {
      type: String,
      default: '100%',
    },
    height: {
      type: String,
      default: '350px',
    },
  },
  emits: ['update:modelValue', 'point', 'addressSelected', 'positionChanged'],

  setup(props, { emit }) {
    // 使用地图store
    const mapStore = useMapStore();
    const map = ref(null);
    const lng = ref(121.478_94);
    const lat = ref(31.223);
    const defaultCityValue = ref(props.cityValue);
    // 搜索相关状态
    const searchAddress = ref(props.defaultSearch);
    const selectedAddress = ref('');
    const searchResults = ref([]);
    const loading = ref(false);

    // 初始化地图配置
    const initMapConfig = async () => {
      try {
        if (!mapStore || typeof mapStore.getMapConfig !== 'function') {
          console.error('地图存储服务不可用');
          message.error('地图服务初始化失败');
          return false;
        }
        const config = await mapStore.getMapConfig();
        if (!config || typeof config !== 'object') {
          console.warn('未获取到有效的地图配置信息');
          return false;
        }
        // 检查必要的配置项是否存在
        if (!config.map_provider) {
          console.warn('地图配置缺少必要的服务商信息');
          // 设置默认服务商
          config.map_provider = 'amap';
        }
        return true;
      } catch (error) {
        console.error('初始化地图配置失败:', error);
        message.error('地图配置加载失败');
        return false;
      }
    };

    // 下拉框引用
    const dropdownRef = ref(null);
    // 控制下拉菜单可见性
    const dropdownVisible = ref(false);
    // 控制模态框可见性
    const modalVisible = ref(false);
    // 经纬度显示文本
    const coordinatesText = ref('');

    // 地址搜索功能
    const handleSearch = async () => {
      // 清空之前的搜索结果
      searchResults.value = [];
      // 关闭下拉菜单
      dropdownVisible.value = false;

      if (!searchAddress.value || !searchAddress.value.trim()) {
        message.warning('请输入搜索地址');
        return;
      }

      const searchTerm = searchAddress.value.trim();

      // 简单的输入验证
      if (searchTerm.length < 2) {
        message.warning('请输入更详细的地址信息');
        return;
      }

      loading.value = true;
      try {
        // 检查并初始化地图配置
        const configInitialized = await initMapConfig();
        if (!configInitialized) {
          message.error('地图服务初始化失败，请刷新页面重试');
          return;
        }

        const mapProvider = mapStore.getMapProvider();
        if (!mapProvider) {
          console.error('未找到地图服务商配置');
          message.error('地图配置错误，请检查设置');
          return;
        }

        // 确保地图API已加载
        if (!window.AMap && !window.BMap && !window.TMap && !window.T) {
          message.warning('地图API正在加载中，请稍后再试');
          return;
        }

        await searchAddressByProvider(mapProvider, searchTerm);
        console.log('搜索结果:', searchResults.value);
      } catch (error) {
        console.error('地址搜索失败:', error);
        message.error('地址搜索失败，请检查网络连接或重试');
        searchResults.value = [];
      } finally {
        loading.value = false;
        // 搜索完成后，如果有结果，自动打开下拉菜单
        if (searchResults.value.length > 0) {
          dropdownVisible.value = true;
        }
      }
    };

    // 根据地图服务商搜索地址
    const searchAddressByProvider = async (provider, address) => {
      return new Promise((resolve, reject) => {
        switch (provider) {
          case 'amap': {
            // 高德地图地址搜索
            try {
              const AMap = window.AMap;
              if (!AMap) {
                message.error('高德地图API未正确加载');
                reject(new Error('高德地图API未正确加载'));
                return;
              }
              const defaultCity =
                props.cityValue || mapStore.getDefaultCity() || '全国';

              AMap.plugin('AMap.PlaceSearch', () => {
                try {
                  const placeSearch = new AMap.PlaceSearch({
                    city: defaultCity,
                    citylimit: true,
                    pageSize: 10,
                  });

                  placeSearch.search(address, (status, result) => {
                    if (
                      status === 'complete' &&
                      result &&
                      result.poiList &&
                      result.poiList.pois &&
                      Array.isArray(result.poiList.pois) &&
                      result.poiList.pois.length > 0
                    ) {
                      const filteredResults = result.poiList.pois
                        .filter((poi) => poi && poi.name && poi.location)
                        .map((poi) => ({
                          name: poi.name,
                          address: poi.address || '',
                          lng: poi.location.lng,
                          lat: poi.location.lat,
                        }));

                      searchResults.value = filteredResults;
                      resolve(filteredResults);
                    } else {
                      searchResults.value = [];
                      console.error(
                        '高德地图搜索状态:',
                        status,
                        '结果:',
                        result,
                      );
                      message.info('未找到相关地址');
                      resolve([]);
                    }
                  });
                } catch (error) {
                  console.error('创建高德地图搜索实例失败:', error);
                  message.error('高德地图搜索初始化失败');
                  searchResults.value = [];
                  reject(error);
                }
              });
            } catch (error) {
              console.error('高德地图搜索异常:', error);
              message.error('高德地图搜索失败');
              searchResults.value = [];
              reject(error);
            }
            break;
          }
          case 'baidu': {
            // 百度地图地址搜索
            try {
              const BMap = window.BMap;
              if (!BMap) {
                message.error('百度地图API未正确加载');
                reject(new Error('百度地图API未正确加载'));
                return;
              }
              const defaultCity =
                props.cityValue || mapStore.getDefaultCity() || '全国';
              const localSearch = new BMap.LocalSearch(defaultCity, {
                onSearchComplete: (results) => {
                  if (
                    localSearch.getStatus() === BMap.StatusCode.OK &&
                    results &&
                    results.getCurrentNumPois &&
                    results.getCurrentNumPois() > 0
                  ) {
                    const searchResultList = [];
                    for (let i = 0; i < results.getCurrentNumPois(); i++) {
                      const poi = results.getPoi(i);
                      if (poi && poi.point) {
                        searchResultList.push({
                          name: poi.title,
                          address: poi.address,
                          lng: poi.point.lng,
                          lat: poi.point.lat,
                        });
                      }
                    }

                    searchResults.value = searchResultList;
                    resolve(searchResultList);
                  } else {
                    searchResults.value = [];
                    console.error(
                      '百度地图搜索状态码:',
                      localSearch.getStatus(),
                    );
                    message.info('未找到相关地址');
                    resolve([]);
                  }
                },
              });
              localSearch.search(address);
            } catch (error) {
              console.error('百度地图搜索异常:', error);
              message.error('百度地图搜索失败');
              searchResults.value = [];
              reject(error);
            }
            break;
          }
          case 'tencent': {
            // 腾讯地图地址搜索
            try {
              const TMap = window.TMap;
              if (!TMap || !TMap.service || !TMap.service.SearchService) {
                message.error('腾讯地图API未正确加载或版本不兼容');
                searchResults.value = [];
                reject(new Error('腾讯地图API未正确加载或版本不兼容'));
                return;
              }

              const searchService = new TMap.service.SearchService();

              if (
                !searchService ||
                typeof searchService.searchRegion !== 'function'
              ) {
                message.error('腾讯地图搜索服务不可用');
                searchResults.value = [];
                reject(new Error('腾讯地图搜索服务不可用'));
                return;
              }

              searchService
                .searchRegion({
                  keyword: address,
                  regionName:
                    props.cityValue || mapStore.getDefaultCity() || '全国',
                  pageSize: 10,
                })
                .then((result) => {
                  if (
                    result &&
                    result.data &&
                    Array.isArray(result.data) &&
                    result.data.length > 0
                  ) {
                    const filteredResults = result.data
                      .filter((item) => item && item.title && item.location)
                      .map((item) => ({
                        name: item.title,
                        address: item.address || '',
                        lng: item.location.lng,
                        lat: item.location.lat,
                      }));

                    searchResults.value = filteredResults;
                    resolve(filteredResults);
                  } else {
                    searchResults.value = [];
                    console.error('腾讯地图搜索结果为空:', result);
                    message.info('未找到相关地址');
                    resolve([]);
                  }
                })
                .catch((error) => {
                  console.error('腾讯地图搜索失败:', error);
                  message.error('地址搜索失败');
                  searchResults.value = [];
                  reject(error);
                });
            } catch (error) {
              console.error('腾讯地图搜索异常:', error);
              message.error('腾讯地图搜索失败');
              searchResults.value = [];
              reject(error);
            }
            break;
          }
          case 'tianditu': {
            // 天地图地址搜索
            try {
              // 检查T API是否加载
              if (window.T) {
                const T = window.T;

                try {
                  // 创建搜索服务实例
                  const tdtMapKey = mapStore.getTdtMapKey();
                  if (!tdtMapKey || tdtMapKey === 'xxx') {
                    console.warn('天地图搜索服务未配置有效的API Key');
                    message.warning('天地图服务未正确配置，请检查API Key');
                    searchResults.value = [];
                    reject(new Error('天地图服务未正确配置，请检查API Key'));
                    return;
                  }

                  const searchService = new T.TSearch({ key: tdtMapKey });

                  // 执行搜索
                  searchService.searchByKeywords(address, {
                    onSearchComplete(result) {
                      try {
                        // 清除之前的搜索结果
                        searchResults.value = [];

                        // 检查搜索结果
                        if (
                          result &&
                          result.getLength &&
                          result.getLength() > 0
                        ) {
                          const poiList = [];
                          for (
                            let i = 0;
                            i < Math.min(result.getLength(), 20);
                            i++
                          ) {
                            // 限制最多显示20条结果
                            try {
                              const poi = result.getPoi(i);
                              if (poi && poi.name && poi.point) {
                                // 添加有效的地址点
                                poiList.push({
                                  name: poi.name,
                                  address: poi.address || poi.name, // 确保地址字段存在
                                  lng:
                                    poi.point.lng || poi.point.longitude || 0,
                                  lat: poi.point.lat || poi.point.latitude || 0,
                                });
                              }
                            } catch (itemError) {
                              console.error(
                                `处理天地图搜索结果项 ${i} 时出错:`,
                                itemError,
                              );
                              // 继续处理下一项
                            }
                          }

                          // 过滤无效结果并设置搜索结果
                          if (poiList.length > 0) {
                            searchResults.value = poiList;
                            // 不再自动选择第一个结果，让用户手动选择
                            resolve(poiList);
                          } else {
                            console.warn('天地图搜索返回结果无效');
                            message.info('未找到有效的地址信息');
                            resolve([]);
                          }
                        } else {
                          console.log('天地图搜索无结果');
                          message.info('未找到相关地址');
                          resolve([]);
                        }
                      } catch (callbackError) {
                        console.error(
                          '处理天地图搜索结果时出错:',
                          callbackError,
                        );
                        message.error('处理搜索结果时发生错误');
                        searchResults.value = [];
                        reject(callbackError);
                      }
                    },
                    onError(error) {
                      console.error('天地图搜索API错误:', error);
                      message.error(
                        `搜索过程中发生错误: ${error && error.message ? error.message : '未知错误'}`,
                      );
                      searchResults.value = [];
                      reject(error);
                    },
                  });
                } catch (searchError) {
                  console.error('创建或执行天地图搜索服务时出错:', searchError);
                  message.error('搜索服务初始化失败');
                  searchResults.value = [];
                  reject(searchError);
                }
              } else {
                console.error('天地图T API未正确加载');
                message.error('地图服务未就绪，请刷新页面重试');
                searchResults.value = [];
                reject(new Error('天地图T API未正确加载'));
              }
            } catch (error) {
              console.error('天地图搜索异常:', error);
              message.error('天地图搜索失败');
              searchResults.value = [];
              reject(error);
            }
            break;
          }
          default: {
            message.warning('当前地图服务商不支持地址搜索');
            resolve([]);
          }
        }
      });
    };

    // 选择地址
    const selectAddress = (address) => {
      selectedAddress.value = address;
      lng.value = address.lng;
      lat.value = address.lat;

      // 关闭下拉菜单
      dropdownVisible.value = false;

      // 重新初始化地图到选中位置
      if (map.value) {
        const mapProvider = mapStore.getMapProvider();

        // 创建信息窗口内容的函数
        const createInfoContent = (lng, lat) => `
          <div style="padding: 10px;">
            <div style="font-weight: bold; margin-bottom: 5px;">${address.name}</div>
            <div style="color: #666; margin-bottom: 5px;">${address.address || '地址信息不详'}</div>
            <div style="color: #999; font-size: 12px;">经纬度: ${lng.toFixed(6)}, ${lat.toFixed(6)}</div>
          </div>
        `;

        const infoContent = createInfoContent(address.lng, address.lat);

        switch (mapProvider) {
          case 'amap': {
            const AMap = window.AMap;
            const point = new AMap.LngLat(address.lng, address.lat);
            map.value.setCenter(point);
            map.value.clearMap();
            const marker = new AMap.Marker({
              position: point,
              draggable: props.draggable,
            });
            map.value.add(marker);

            // 创建信息窗口
            const infoWindow = new AMap.InfoWindow({
              content: infoContent,
              offset: new AMap.Pixel(0, -30),
            });
            infoWindow.open(map.value, point);

            // 如果支持拖拽，添加拖拽过程和结束事件
            if (props.draggable) {
              // 拖拽移动中实时更新经纬度
              marker.on('dragging', () => {
                const position = marker.getPosition();
                lng.value = position.lng;
                lat.value = position.lat;
                // 同时更新selectedAddress中的经纬度，确保详情显示更新
                if (selectedAddress.value) {
                  selectedAddress.value.lng = position.lng;
                  selectedAddress.value.lat = position.lat;
                }
                // 更新信息窗口内容
                infoWindow.setContent(
                  createInfoContent(position.lng, position.lat),
                );
                // 发出实时更新事件
                emit('point', position.lng, position.lat);
              });

              // 拖拽结束事件
              marker.on('dragend', () => {
                const position = marker.getPosition();
                lng.value = position.lng;
                lat.value = position.lat;
                // 同时更新selectedAddress中的经纬度，确保详情显示更新
                if (selectedAddress.value) {
                  selectedAddress.value.lng = position.lng;
                  selectedAddress.value.lat = position.lat;
                }
                emit('update:modelValue', [position.lng, position.lat]);
                emit('point', position.lng, position.lat);
                // 发出位置变化事件
                emit('positionChanged', {
                  lng: position.lng,
                  lat: position.lat,
                });
              });
            }
            break;
          }
          case 'baidu': {
            const BMap = window.BMap;
            const point = new BMap.Point(address.lng, address.lat);
            map.value.clearOverlays();
            map.value.centerAndZoom(point, 15);
            const marker = new BMap.Marker(point);
            map.value.addOverlay(marker);

            // 创建信息窗口
            const infoWindow = new BMap.InfoWindow(infoContent);
            infoWindow.open(map.value, point);

            // 如果支持拖拽，添加拖拽过程和结束事件
            if (props.draggable) {
              marker.enableDragging();

              // 拖拽移动中实时更新经纬度
              marker.addEventListener('draging', (e) => {
                lng.value = e.point.lng;
                lat.value = e.point.lat;
                // 同时更新selectedAddress中的经纬度，确保详情显示更新
                if (selectedAddress.value) {
                  selectedAddress.value.lng = e.point.lng;
                  selectedAddress.value.lat = e.point.lat;
                }
                // 更新信息窗口内容
                const newInfoWindow = new BMap.InfoWindow(
                  createInfoContent(e.point.lng, e.point.lat),
                );
                newInfoWindow.open(map.value, e.point);
                // 发出实时更新事件
                emit('point', e.point.lng, e.point.lat);
              });

              // 拖拽结束事件
              marker.addEventListener('dragend', (e) => {
                lng.value = e.point.lng;
                lat.value = e.point.lat;
                // 同时更新selectedAddress中的经纬度，确保详情显示更新
                if (selectedAddress.value) {
                  selectedAddress.value.lng = e.point.lng;
                  selectedAddress.value.lat = e.point.lat;
                }
                emit('update:modelValue', [e.point.lng, e.point.lat]);
                emit('point', e.point.lng, e.point.lat);
                // 发出位置变化事件
                emit('positionChanged', { lng: e.point.lng, lat: e.point.lat });
              });
            }
            break;
          }
          case 'tencent': {
            const qq_maps = window.qq.maps;
            const point = new qq_maps.LatLng(address.lat, address.lng);
            map.value.setCenter(point);
            map.value.clearOverlays();
            const marker = new qq_maps.Marker({
              position: point,
              draggable: props.draggable,
              map: map.value,
            });

            // 创建信息窗口
            let infoWindow = new qq_maps.InfoWindow({
              content: infoContent,
              position: point,
            });
            infoWindow.open();

            // 如果支持拖拽，添加拖拽过程和结束事件
            if (props.draggable) {
              // 拖拽移动中实时更新经纬度
              qq_maps.event.addListener(marker, 'drag', (e) => {
                const lngValue = e.latLng.getLng();
                const latValue = e.latLng.getLat();
                lng.value = lngValue;
                lat.value = latValue;
                // 同时更新selectedAddress中的经纬度，确保详情显示更新
                if (selectedAddress.value) {
                  selectedAddress.value.lng = lngValue;
                  selectedAddress.value.lat = latValue;
                }
                // 更新信息窗口内容
                infoWindow.close();
                infoWindow = new qq_maps.InfoWindow({
                  content: createInfoContent(lngValue, latValue),
                  position: e.latLng,
                });
                infoWindow.open();
                // 发出实时更新事件
                emit('point', lngValue, latValue);
              });

              // 拖拽结束事件
              qq_maps.event.addListener(marker, 'dragend', (e) => {
                const lngValue = e.latLng.getLng();
                const latValue = e.latLng.getLat();
                lng.value = lngValue;
                lat.value = latValue;
                // 同时更新selectedAddress中的经纬度，确保详情显示更新
                if (selectedAddress.value) {
                  selectedAddress.value.lng = lngValue;
                  selectedAddress.value.lat = latValue;
                }
                emit('update:modelValue', [lngValue, latValue]);
                emit('point', lngValue, latValue);
                // 发出位置变化事件
                emit('positionChanged', { lng: lngValue, lat: latValue });
              });
            }
            break;
          }
          case 'tianditu': {
            const T = window.T;
            const point = new T.LngLat(address.lng, address.lat);
            map.value.clearOverLays();
            map.value.centerAndZoom(point, 15);
            const marker = new T.Marker(point);
            map.value.addOverLay(marker);

            // 创建信息窗口
            const infoWindow = new T.InfoWindow();
            infoWindow.setContent(infoContent);
            infoWindow.open(map.value, point);

            // 如果支持拖拽，添加拖拽过程和结束事件
            if (props.draggable) {
              // 拖拽移动中实时更新经纬度
              T.event.addListener(marker, 'drag', () => {
                const pos = marker.getLngLat();
                lng.value = pos.lng;
                lat.value = pos.lat;
                // 同时更新selectedAddress中的经纬度，确保详情显示更新
                if (selectedAddress.value) {
                  selectedAddress.value.lng = pos.lng;
                  selectedAddress.value.lat = pos.lat;
                }
                // 更新信息窗口内容
                infoWindow.setContent(createInfoContent(pos.lng, pos.lat));
                infoWindow.open(map.value, pos);
                // 发出实时更新事件
                emit('point', pos.lng, pos.lat);
              });

              // 拖拽结束事件
              T.event.addListener(marker, 'dragend', () => {
                const pos = marker.getLngLat();
                lng.value = pos.lng;
                lat.value = pos.lat;
                // 同时更新selectedAddress中的经纬度，确保详情显示更新
                if (selectedAddress.value) {
                  selectedAddress.value.lng = pos.lng;
                  selectedAddress.value.lat = pos.lat;
                }
                emit('update:modelValue', [pos.lng, pos.lat]);
                emit('point', pos.lng, pos.lat);
                // 发出位置变化事件
                emit('positionChanged', { lng: pos.lng, lat: pos.lat });
              });
            }
            break;
          }
        }
      }

      // 发出更新事件
      emit('update:modelValue', [address.lng, address.lat]);
      emit('point', address.lng, address.lat);

      // 发出选择完成事件，传递完整地址信息
      emit('addressSelected', address);
    };
    // 更新经纬度显示文本
    const updateCoordinatesText = () => {
      coordinatesText.value =
        lng.value && lat.value
          ? `[${lng.value.toFixed(6)}, ${lat.value.toFixed(6)}]`
          : '';
    };

    // 打开模态框
    const openModal = () => {
      modalVisible.value = true;
      // 地图初始化由watch模态框可见性变化处理
    };

    // 关闭模态框
    const closeModal = () => {
      modalVisible.value = false;
    };

    // 确认选择位置
    const confirmLocation = () => {
      if (lng.value && lat.value) {
        emit('update:modelValue', [lng.value, lat.value]);
        emit('positionChanged', { lng: lng.value, lat: lat.value });
        updateCoordinatesText();
        closeModal();
      } else {
        message.warning('请先选择有效位置');
      }
    };

    watch(
      () => props.modelValue,
      (newValue) => {
        // 如果传入的是经纬度数组，直接更新组件内的坐标值
        if (newValue && Array.isArray(newValue) && newValue.length === 2) {
          lng.value = newValue[0];
          lat.value = newValue[1];
          updateCoordinatesText();
          if (modalVisible.value) {
            init();
          }
        }
      },
      { immediate: true },
    );

    // 监听lng和lat变化，更新显示文本
    watch([lng, lat], () => {
      updateCoordinatesText();
    });

    // 监听defaultSearch变化，自动搜索并选择第一个地址
    watch(
      () => props.defaultSearch,
      (newSearchText) => {
        // 只有当模态框打开时才处理搜索
        if (modalVisible.value && newSearchText && newSearchText.trim()) {
          // 更新搜索框的值
          searchAddress.value = newSearchText;

          // 触发搜索
          performSearchAndSelect();
        }
      },
      { immediate: false }, // 移除immediate，避免初始加载时触发
    );
    watch(
      () => props.cityValue,
      (val) => {
        defaultCityValue.value = val;
      },
      { immediate: false }, // 移除immediate，避免初始加载时触发
    );

    // 监听模态框可见性变化
    watch(
      () => modalVisible.value,
      async (isVisible) => {
        if (isVisible) {
          // 模态框打开时，确保地图初始化
          await nextTick();
          if (!map.value) {
            // 首先加载地图资源并等待加载完成
            try {
              const resourcesLoaded = await loadMapResources();
              if (resourcesLoaded) {
                await init();
              }
            } catch (error) {
              console.error('地图初始化失败:', error);
              message.error('地图初始化失败，请稍后重试');
            }
          }

          // 如果有defaultSearch值，执行搜索并选择第一个地址
          if (props.defaultSearch && props.defaultSearch.trim()) {
            searchAddress.value = props.defaultSearch;
            await performSearchAndSelect();
          }
        }
      },
    );

    // 封装搜索并选择第一个地址的逻辑
    const performSearchAndSelect = async () => {
      try {
        await handleSearch();
        // 如果有搜索结果，自动选择第一个地址
        if (searchResults.value && searchResults.value.length > 0) {
          selectAddress(searchResults.value[0]);
        }
      } catch (error) {
        console.error('自动搜索和选择地址失败:', error);
      }
    };
    onMounted(async () => {
      // 只初始化地图配置，不加载地图资源
      await initMapConfig();
    });

    // 动态加载地图脚本
    const loadMapResources = async () => {
      const configInitialized = await initMapConfig();
      if (!configInitialized) {
        console.warn('地图配置初始化失败');
        return false;
      }
      return await load_map_script(); // 加载地图资源并等待完成
    };
    const load_map_script = () => {
      return new Promise((resolve, reject) => {
        // 此处在所需页面引入资源就是，不用再public/index.html中引入
        try {
          // 清理旧的脚本标签
          const loadmap = document.querySelectorAll('.loadmap');
          if (loadmap && loadmap.length > 0) {
            // 每次append script之前判断一下，避免重复添加script资源标签
            for (const element of loadmap) {
              element.remove();
            }
          }

          // 创建新的脚本标签
          const script = document.createElement('script');
          script.type = 'text/javascript';
          script.className = 'loadmap'; // 给script一个类名
          script.async = true; // 异步加载

          // 根据map store中的配置获取地图服务商
          const mapProvider = mapStore.getMapProvider();

          if (!mapProvider) {
            console.error('未找到地图服务商配置');
            message.error('地图配置错误，请检查设置');
            reject(new Error('未找到地图服务商配置'));
            return;
          }

          // 根据地图服务商设置脚本源
          switch (mapProvider) {
            case 'amap': {
              // 高德地图
              const amapVersion = mapStore.getAmapVersion() || '1.4.15';
              const amapKey = mapStore.getAmapKey() || '';
              const amapPlugins =
                mapStore.getAmapPlugins() ||
                'AMap.ToolBar,AMap.Geocoder,AMap.PlaceSearch';

              // 设置高德地图安全配置
              window._AMapSecurityConfig = {
                securityJsCode: mapStore.getAmapSecurityJsCode() || '',
              };

              script.src = `https://webapi.amap.com/maps?v=${amapVersion}&key=${amapKey || 'xxx'}&plugin=${amapPlugins}`;
              break;
            }
            case 'baidu': {
              // 百度地图
              const baiduVersion = mapStore.getBaiduVersion() || '3.0';
              const baiduKey = mapStore.getBaiduKey() || '';
              script.src = `https://api.map.baidu.com/api?v=${baiduVersion}&ak=${baiduKey || 'xxx'}`;
              break;
            }
            case 'tencent': {
              // 腾讯地图
              const tencentKey = mapStore.getTencentKey() || '';
              script.src = `https://map.qq.com/api/js?v=2.exp&key=${tencentKey || 'xxx'}`;
              break;
            }
            case 'tianditu': {
              // 天地图
              const tiandituKey = mapStore.getTiandituKey() || '';
              script.src = `https://api.tianditu.gov.cn/api?v=4.0&tk=${tiandituKey || 'xxx'}`;
              break;
            }
            default: {
              console.error('不支持的地图服务商:', mapProvider);
              message.error('不支持的地图服务商');
              reject(new Error('不支持的地图服务商'));
              return;
            }
          }

          // 设置脚本加载完成回调
          script.addEventListener('load', () => {
            console.log('地图脚本加载成功');
            resolve(true);
          });

          // 设置脚本加载失败回调
          script.onerror = (error) => {
            console.error('地图脚本加载失败:', error);
            message.error('地图资源加载失败');
            reject(new Error('地图脚本加载失败'));
          };

          // 添加脚本到文档
          document.head.append(script);
        } catch (error) {
          console.error('创建地图脚本时出错:', error);
          reject(error);
        }
      });
    };

    // The map loading logic is already implemented in the load_map_script function above

    const load_tx_map = () => {
      // 此处在所需页面引入资源就是，不用再public/index.html中引入
      try {
        // 清理旧的脚本标签
        const loadmap2 = document.querySelectorAll('.loadmap2');
        if (loadmap2 && loadmap2.length > 0) {
          // 每次append script之前判断一下，避免重复添加script资源标签
          for (const element of loadmap2) {
            element.remove();
          }
        }

        // 创建新的脚本标签
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.className = 'loadmap2'; // 给script一个类名
        script.async = true; // 异步加载

        const tencentKey = mapStore.getTencentMapKey() || '';
        script.src = `https://map.qq.com/api/gljs?v=1.exp&key=${tencentKey || 'xxx'}&libraries=service`;

        // 错误处理
        script.onerror = (error) => {
          console.error('腾讯地图GLJS加载失败:', error);
          message.warning('腾讯地图高级功能加载失败，但基础功能仍可使用');
        };

        // 成功加载处理
        script.addEventListener('load', () => {
          console.log('腾讯地图GLJS脚本加载成功');
        });

        document.body.append(script);
      } catch (error) {
        console.error('加载腾讯地图GLJS时出错:', error);
        // 非致命错误，允许继续使用基础地图功能
      }
    };
    // 初始化地图
    const init = () => {
      // 使用nextTick确保DOM已更新，地图容器存在
      nextTick(() => {
        // 检查地图容器是否存在
        const mapContainer = document.querySelector('#map');
        if (!mapContainer) {
          return;
        }

        // 根据map store中的配置获取地图服务商
        const mapProvider = mapStore.getMapProvider();
        switch (mapProvider) {
          case 'amap': {
            const AMap = window.AMap;
            // 检查AMap API是否已加载完成
            if (!AMap || !AMap.Map) {
              console.error('AMap API未加载完成，无法初始化地图');
              message.error('地图资源加载中，请稍后再试');
              return;
            }

            const defaultZoom = Number.parseInt(
              mapStore.getDefaultZoom() || '13',
            );
            const defaultCity =
              props.cityValue || mapStore.getDefaultCity() || '全国';

            try {
              map.value = new AMap.Map('map', {
                zoomEnable: true,
                resizeEnable: true,
                scrollWheel: false,
                zoom: defaultZoom, // 使用store中的默认缩放级别
                center: [lng.value, lat.value], // 初始化地图中心点位置
                defaultCity, // 使用store中的默认城市
              });
            } catch (error) {
              console.error('创建高德地图实例失败:', error);
              message.error('地图初始化失败');
              return;
            }

            // 确保map.value已正确初始化再继续执行
            if (map.value) {
              AMap.plugin(['AMap.ToolBar'], () => {
                // 在图面添加工具条控件, 工具条控件只有缩放功能
                if (map.value) map.value.addControl(new AMap.ToolBar());
              });

              // 创建标注
              const marker_config = {
                position: map.value.getCenter(),
                // offset: new AMap.Pixel(-13, -30),
                draggable: props.draggable,
              };
              const marker4 = new AMap.Marker(marker_config);
              marker4.setMap(map.value);
              // 标注可拖拽回调
              if (props.draggable) {
                marker4.on('dragend', (e) => {
                  map.value.panTo(e.lnglat);
                  lng.value = e.lnglat.lng;
                  lat.value = e.lnglat.lat;
                  // 同时更新selectedAddress中的经纬度，确保详情显示更新
                  if (selectedAddress.value) {
                    selectedAddress.value.lng = e.lnglat.lng;
                    selectedAddress.value.lat = e.lnglat.lat;
                  }
                  emit('point', lng.value, lat.value);
                });
              }
              map.value.add(marker4);
            }
            break;
          }
          case 'baidu': {
            const BMap = window.BMap;
            map.value = new BMap.Map('map', {
              enableMapClick: false,
            });
            const point2 = new BMap.Point(lng.value, lat.value);
            map.value.centerAndZoom(point2, 10); // 初始化地图,设置中心点坐标和地图级别
            // 添加控件
            const navigationControl = new BMap.NavigationControl({
              // 靠左上角位置
              anchor: window.BMAP_ANCHOR_TOP_LEFT,
              // LARGE类型
              type: window.BMAP_NAVIGATION_CONTROL_LARGE,
            });
            map.value.addControl(navigationControl);
            const marker2 = new BMap.Marker(point2);
            map.value.addOverlay(marker2);
            if (props.draggable) {
              // 修正marker的初始化
              marker2.enableDragging();
              marker2.addEventListener('dragend', (e) => {
                map.value.panTo(e.point);
                lat.value = e.point.lat;
                lng.value = e.point.lng;
                // 同时更新selectedAddress中的经纬度，确保详情显示更新
                if (selectedAddress.value) {
                  selectedAddress.value.lng = e.point.lng;
                  selectedAddress.value.lat = e.point.lat;
                }
                emit('point', lng.value, lat.value);
              });

              // 设置标注提示信息
              const cr = new BMap.CopyrightControl({
                anchor: window.BMAP_ANCHOR_BOTTOM_RIGHT,
              });
              map.value.addControl(cr); // 添加版权控件
              const bs = map.value.getBounds(); // 返回地图可视区域
              cr.addCopyright({
                id: 1,
                content:
                  '<div class="map-dragging-tips"><span>' +
                  '拖动红色图标直接定位' +
                  '</span></div>',
                bounds: bs,
              });
            }
            break;
          }
          case 'tencent': {
            const qq_maps = window.qq.maps;
            const point3 = new qq_maps.LatLng(lat.value, lng.value);
            map.value = new qq_maps.Map('map', {
              center: point3,
              zoom: 10,
            });
            const marker3 = new qq_maps.Marker({
              map: map.value,
              position: point3,
              draggable: props.draggable,
            });
            qq_maps.event.addListener(marker3, 'dragend', (e) => {
              lat.value = e.latLng.lat;
              lng.value = e.latLng.lng;
              map.value.panTo(e.latLng);
              // 同时更新selectedAddress中的经纬度，确保详情显示更新
              if (selectedAddress.value) {
                selectedAddress.value.lng = e.latLng.lng;
                selectedAddress.value.lat = e.latLng.lat;
              }
              emit('point', lng.value, lat.value);
            });
            break;
          }
          case 'tianditu': {
            const T = window.T;
            // 坐标
            map.value = new T.Map('map');
            const point = new T.LngLat(lng.value, lat.value);
            map.value.centerAndZoom(point, 10);
            // 禁止鼠标滚动缩小放大
            map.value.disableScrollWheelZoom();

            // 添加控件
            // 创建缩放平移控件对象
            const control = new T.Control.Zoom();
            // control.setPosition(T_ANCHOR_TOP_RIGHT);
            // 添加缩放平移控件
            map.value.addControl(control);

            map.value.clearOverLays();
            const marker = new T.Marker(point);
            map.value.addOverLay(marker);
            if (props.draggable) {
              marker.enableDragging();
              marker.addEventListener('dragend', (e) => {
                map.value.panTo(new T.LngLat(e.lnglat.lng, e.lnglat.lat));
                lat.value = e.lnglat.lat;
                lng.value = e.lnglat.lng;
                // 同时更新selectedAddress中的经纬度，确保详情显示更新
                if (selectedAddress.value) {
                  selectedAddress.value.lng = e.lnglat.lng;
                  selectedAddress.value.lat = e.lnglat.lat;
                }
                emit('point', lng.value, lat.value);
              });
            }
            break;
          }
          default: {
            console.error('不支持的地图服务商:', mapProvider);
            message.error('地图初始化失败：不支持的服务商');
            break;
          }
        }
      });
    };
    const map_event = (value) => {
      // 根据map store中的配置获取地图服务商
      const mapProvider = mapStore.getMapProvider();
      switch (mapProvider) {
        case 'amap': {
          // 高德地图地址解析
          try {
            const AMap = window.AMap;
            const defaultCity =
              props.cityValue || mapStore.getDefaultCity() || '全国';

            AMap.plugin('AMap.Geocoder', () => {
              new AMap.Geocoder({
                city: defaultCity, // 使用store中的默认城市
              }).getLocation(value, (status, result) => {
                if (
                  status === 'complete' &&
                  result.geocodes &&
                  result.geocodes.length > 0
                ) {
                  const lnglat = result.geocodes[0].location;
                  lng.value = lnglat.lng;
                  lat.value = lnglat.lat;
                  init();
                  emit('point', lng.value, lat.value);
                } else {
                  message.info('您选择地址没有解析到结果！');
                }
              });
            });
          } catch (error) {
            console.error('高德地图地址解析失败:', error);
            message.error('地址解析失败');
          }
          break;
        }
        case 'baidu': {
          // 百度地图地址解析
          try {
            // 创建地址解析器实例
            const geo2 = new window.BMap.Geocoder();
            const defaultCity =
              props.cityValue || mapStore.getDefaultCity() || '全国';
            // 将地址解析结果显示在地图上,并调整地图视野
            geo2.getPoint(
              value,
              (point) => {
                if (point) {
                  lng.value = point.lng;
                  lat.value = point.lat;
                  emit('point', lng.value, lat.value);
                  init();
                } else {
                  message.info('您选择地址没有解析到结果！');
                }
              },
              defaultCity,
            );
          } catch (error) {
            console.error('百度地图地址解析失败:', error);
            message.error('地址解析失败');
          }
          break;
        }
        case 'tencent': {
          // 腾讯地图地址解析
          try {
            const geo3 = new window.TMap.service.Geocoder();
            geo3
              .getLocation({ address: value })
              .then((result) => {
                if (result && result.result && result.result.location) {
                  const lnglat = result.result.location;
                  lng.value = lnglat.lng;
                  lat.value = lnglat.lat;
                  init();
                  emit('point', lng.value, lat.value);
                } else {
                  message.info('您选择地址没有解析到结果！');
                }
              })
              .catch((error) => {
                console.error('腾讯地图地址解析失败:', error);
                message.error('地址解析失败');
              });
          } catch (error) {
            console.error('腾讯地图地址解析失败:', error);
            message.error('地址解析失败');
          }
          break;
        }
        case 'tianditu': {
          // 天地图地址解析
          try {
            const geo = new window.T.Geocoder();
            geo.getPoint(value, (result) => {
              if (result && result.getStatus() === 0) {
                const point = result.getLocationPoint();
                lng.value = point.lng;
                lat.value = point.lat;
                init();
                map.value.panTo(new window.T.LngLat(lng.value, lat.value));
                emit('point', lng.value, lat.value);
              } else {
                message.info('您选择地址没有解析到结果！');
              }
            });
          } catch (error) {
            console.error('天地图地址解析失败:', error);
            message.error('地址解析失败');
          }
          break;
        }
      }
    };
    // 返回模板需要使用的响应式数据和方法
    return {
      map,
      lng,
      lat,
      searchAddress,
      selectedAddress,
      searchResults,
      loading,
      handleSearch,
      selectAddress,
      dropdownRef,
      dropdownVisible,
      modalVisible,
      coordinatesText,
      openModal,
      closeModal,
      confirmLocation,
      defaultCityValue,
    };
  },
});
</script>
<template>
  <div class="map-coordinate-container">
    <!-- 输入框和按钮部分 -->
    <AInputGroup compact>
      <AInput
        v-model:value="coordinatesText"
        placeholder="经纬度坐标"
        style="width: calc(100% - 90px)"
        :disabled="true"
      />
      <AButton type="primary" @click="openModal">选择位置</AButton>
    </AInputGroup>

    <!-- 地图模态框 -->
    <AModal
      v-model:open="modalVisible"
      title="选择位置"
      width="70%"
      :footer="null"
    >
      <div class="map-modal-content">
        <!-- 搜索区域 -->
        <div class="search-section">
          <ADropdown>
            <AInputGroup compact>
              <AInput
                v-model:value="searchAddress"
                placeholder="请输入地址进行搜索"
                style="width: calc(100% - 80px)"
                @press-enter="handleSearch"
              >
                <template #prefix>
                  {{ defaultCityValue }}
                </template>
              </AInput>
              <AButton type="primary" @click="handleSearch">搜索</AButton>
            </AInputGroup>
            <template #overlay>
              <AMenu>
                <AMenuItem
                  :key="index"
                  v-for="(item, index) in searchResults"
                  @click="selectAddress(item)"
                >
                  {{ item.name + (item.address ? ` - ${item.address}` : '') }}
                </AMenuItem>
              </AMenu>
            </template>
          </ADropdown>
        </div>

        <!-- 地图 -->
        <div class="map-wrapper">
          <div id="map" class="map radius-md" :style="{ width, height }"></div>
        </div>

        <!-- 地址详情 -->
        <div v-if="selectedAddress" class="address-info">
          <ADescriptions title="地址详情" size="small" :column="1">
            <ADescriptionsItem label="地址名称">
              {{ selectedAddress.name }}
            </ADescriptionsItem>
            <ADescriptionsItem label="详细地址">
              {{ selectedAddress.address }}
            </ADescriptionsItem>
            <ADescriptionsItem label="经度">
              {{ selectedAddress.lng }}
            </ADescriptionsItem>
            <ADescriptionsItem label="纬度">
              {{ selectedAddress.lat }}
            </ADescriptionsItem>
          </ADescriptions>
        </div>

        <!-- 模态框底部按钮 -->
        <div class="modal-footer">
          <AButton @click="closeModal">取消</AButton>
          <AButton type="primary" @click="confirmLocation">确认选择</AButton>
        </div>
      </div>
    </AModal>
  </div>
</template>
<style lang="scss" scoped>
.map-coordinate-container {
  width: 100%;
}

.map-modal-content {
  padding: 8px 0;
}

.search-section {
  margin-bottom: 16px;
}

/* 下拉菜单样式通过Ant Design Vue内置样式实现 */
:deep(.ant-dropdown-menu-item) {
  padding: 8px 16px;
  cursor: pointer;
}

:deep(.ant-dropdown-menu-item:hover) {
  background-color: #f5f5f5;
}

.map-wrapper {
  margin-bottom: 16px;
  overflow: hidden;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgb(0 0 0 / 10%);
}

.map {
  width: 100%;
  height: 350px;
}

.address-info {
  padding: 16px;
  margin-bottom: 16px;
  background: #fafafa;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
}

.modal-footer {
  padding-top: 16px;
  margin-top: 8px;
  text-align: right;
  border-top: 1px solid #f0f0f0;
}

:deep(.ant-descriptions-title) {
  margin-bottom: 12px;
  font-weight: 500;
  color: #262626;
}

:deep(.ant-descriptions-item-label) {
  width: 80px;
  font-weight: 500;
  color: #595959;
}

:deep(.ant-descriptions-item-content) {
  color: #262626;
}
</style>
